package com.campus.food.controller;

import com.campus.food.model.dto.OrderDTO;
import com.campus.food.model.entity.Order;
import com.campus.food.model.entity.OrderDetail;
import com.campus.food.service.OrderService;
import com.campus.food.util.Result;
import com.campus.food.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

/**
 * 订单控制器
 * 处理订单相关的HTTP请求
 * 
 * @author Claude3.7 Sonnet
 * @since 2025-05-29
 */
@RestController
@RequestMapping("/api/orders")
@Validated
public class OrderController {
    
    @Autowired
    private OrderService orderService;
    
    /**
     * 创建订单
     * POST /api/orders/create
     */
    @PostMapping("/create")
    public Result<Order> createOrder(@Valid @RequestBody OrderDTO orderDTO) {
        try {
            // 将DTO转换为Order实体
            Order order = convertToOrder(orderDTO);
            Order savedOrder = orderService.createOrder(order);
            return Result.success("订单创建成功", savedOrder);
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("创建订单失败，请稍后重试");
        }
    }
    
    /**
     * 根据ID获取订单信息
     * GET /api/orders/{id}
     */
    @GetMapping("/{id}")
    public Result<Order> getOrderById(@PathVariable @NotNull Long id) {
        try {
            Order order = orderService.getOrderById(id);
            return Result.success(order);
        }  catch (Exception e) {
            e.printStackTrace();
            return Result.error("获取订单信息失败");
        }
    }
    
    /**
     * 根据订单号获取订单信息
     * GET /api/orders/no/{orderNo}
     */
    @GetMapping("/no/{orderNo}")
    public Result<Order> getOrderByOrderNo(@PathVariable String orderNo) {
        try {
            Order order = orderService.getOrderByOrderNo(orderNo);
            return Result.success(order);
        } catch (BusinessException e) {
            return Result.notFound(e.getMessage());
        } catch (Exception e) {
            return Result.error("获取订单信息失败");
        }
    }
    
    /**
     * 更新订单信息
     * PUT /api/orders/{id}
     */
    @PutMapping("/{id}")
    public Result<String> updateOrder(@PathVariable @NotNull Long id,
                                    @RequestBody Order order) {
        try {
            order.setId(id);
            boolean success = orderService.updateOrder(order);
            if (success) {
                return Result.success("订单更新成功");
            } else {
                return Result.error("订单更新失败");
            }
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("更新订单失败");
        }
    }
    
    /**
     * 更新订单状态
     * PUT /api/orders/{id}/status
     */
    @PutMapping("/{id}/status")
    public Result<String> updateOrderStatus(@PathVariable @NotNull Long id,
                                          @RequestParam @NotNull Integer status) {
        try {
            boolean success = orderService.updateOrderStatus(id, status);
            if (success) {
                String message = getStatusMessage(status);
                return Result.success(message);
            } else {
                return Result.error("状态更新失败");
            }
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("更新订单状态失败");
        }
    }
    
    /**
     * 支付订单
     * POST /api/orders/{id}/pay
     */
    @PostMapping("/{id}/pay")
    public Result<String> payOrder(@PathVariable @NotNull Long id,
                                 @RequestParam @NotNull Integer paymentMethod) {
        try {
            boolean success = orderService.payOrder(id, paymentMethod);
            if (success) {
                return Result.success("支付成功");
            } else {
                return Result.error("支付失败");
            }
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("支付订单失败");
        }
    }
    
    /**
     * 确认订单（商家端）
     * POST /api/orders/{id}/confirm
     */
    @PostMapping("/{id}/confirm")
    public Result<String> confirmOrder(@PathVariable @NotNull Long id,
                                     @RequestParam @NotNull Long merchantId) {
        try {
            boolean success = orderService.confirmOrder(id, merchantId);
            if (success) {
                return Result.success("订单确认成功");
            } else {
                return Result.error("订单确认失败");
            }
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("确认订单失败");
        }
    }
    
    /**
     * 开始配送（商家端）
     * POST /api/orders/{id}/deliver
     */
    @PostMapping("/{id}/deliver")
    public Result<String> startDelivery(@PathVariable @NotNull Long id,
                                      @RequestParam @NotNull Long merchantId) {
        try {
            boolean success = orderService.startDelivery(id, merchantId);
            if (success) {
                return Result.success("开始配送");
            } else {
                return Result.error("配送失败");
            }
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("开始配送失败");
        }
    }
    
    /**
     * 确认收货（用户端）
     * POST /api/orders/{id}/complete
     */
    @PostMapping("/{id}/complete")
    public Result<String> completeOrder(@PathVariable @NotNull Long id,
                                      @RequestParam @NotNull Long userId) {
        try {
            boolean success = orderService.completeOrder(id, userId);
            if (success) {
                return Result.success("确认收货成功");
            } else {
                return Result.error("确认收货失败");
            }
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("确认收货失败");
        }
    }
    
    /**
     * 取消订单
     * POST /api/orders/{id}/cancel
     */
    @PostMapping("/{id}/cancel")
    public Result<String> cancelOrder(@PathVariable @NotNull Long id,
                                    @RequestParam @NotNull String cancelReason,
                                    @RequestParam @NotNull Long operatorId) {
        try {
            boolean success = orderService.cancelOrder(id, cancelReason, operatorId);
            if (success) {
                return Result.success("订单取消成功");
            } else {
                return Result.error("订单取消失败");
            }
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("取消订单失败");
        }
    }
    
    /**
     * 删除订单（管理员专用）
     * DELETE /api/orders/{id}
     */
    @DeleteMapping("/{id}")
    public Result<String> deleteOrder(@PathVariable @NotNull Long id) {
        try {
            boolean success = orderService.deleteOrder(id);
            if (success) {
                return Result.success("订单删除成功");
            } else {
                return Result.error("订单删除失败");
            }
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("删除订单失败");
        }
    }
    
    /**
     * 获取用户订单列表（用户端）
     * GET /api/orders/user/{userId}
     */
    @GetMapping("/user/{userId}")
    public Result<List<Order>> getUserOrders(@PathVariable @NotNull Long userId,
                                           @RequestParam(defaultValue = "1") int page,
                                           @RequestParam(defaultValue = "10") int size,
                                           @RequestParam(required = false) Integer status) {
        try {
            List<Order> orders = orderService.getUserOrders(userId, page, size, status);
            long total = orderService.getUserOrderCount(userId, status);
            return Result.success(orders, total);
        }  catch (Exception e) {
            e.printStackTrace();
            return Result.error("获取订单列表失败");
        }
    }
    
    /**
     * 获取商家订单列表（商家端）
     * GET /api/orders/merchant/{merchantId}
     */
    @GetMapping("/merchant/{merchantId}")
    public Result<List<Order>> getMerchantOrders(@PathVariable @NotNull Long merchantId,
                                               @RequestParam(defaultValue = "1") int page,
                                               @RequestParam(defaultValue = "10") int size,
                                               @RequestParam(required = false) Integer status) {
        try {
            List<Order> orders = orderService.getMerchantOrders(merchantId, page, size, status);
            long total = orderService.getMerchantOrderCount(merchantId, status);
            return Result.success(orders, total);
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("获取订单列表失败");
        }
    }
    
    /**
     * 获取所有订单列表（管理员专用）
     * GET /api/orders/admin
     */
    @GetMapping("/admin")
    public Result<List<Order>> getAllOrders(@RequestParam(defaultValue = "1") int page,
                                          @RequestParam(defaultValue = "10") int size,
                                          @RequestParam(required = false) String orderNo,
                                          @RequestParam(required = false) Integer status,
                                          @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
                                          @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        try {
            List<Order> orders = orderService.getAllOrders(page, size, orderNo, status, startTime, endTime);
            long total = orderService.getAllOrderCount(orderNo, status, startTime, endTime);
            return Result.success(orders, total);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("获取订单列表失败");
        }
    }
    
    /**
     * 根据状态获取订单列表
     * GET /api/orders/status/{status}
     */
    @GetMapping("/status/{status}")
    public Result<List<Order>> getOrdersByStatus(@PathVariable @NotNull Integer status) {
        try {
            List<Order> orders = orderService.getOrdersByStatus(status);
            return Result.success(orders);
        } catch (Exception e) {
            return Result.error("获取订单列表失败");
        }
    }
    
    /**
     * 获取用户在指定商家的订单数量
     * GET /api/orders/count/user/{userId}/merchant/{merchantId}
     */
    @GetMapping("/count/user/{userId}/merchant/{merchantId}")
    public Result<Long> getUserOrderCountByMerchant(@PathVariable @NotNull Long userId,
                                                  @PathVariable @NotNull Long merchantId) {
        try {
            long count = orderService.getUserOrderCountByMerchant(userId, merchantId);
            return Result.success(count);
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("获取订单数量失败");
        }
    }
    
    /**
     * 获取时间范围内的订单数量
     * GET /api/orders/count/time-range
     */
    @GetMapping("/count/time-range")
    public Result<Long> getOrderCountByTimeRange(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
                                               @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
                                               @RequestParam(required = false) Integer status) {
        try {
            long count = orderService.getOrderCountByTimeRange(startTime, endTime, status);
            return Result.success(count);
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("获取订单数量失败");
        }
    }
    
    /**
     * 获取时间范围内的销售额
     * GET /api/orders/sales/time-range
     */
    @GetMapping("/sales/time-range")
    public Result<Double> getSalesAmountByTimeRange(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDateTime startTime,
                                                  @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDateTime endTime,
                                                  @RequestParam(required = false) Integer status) {
        try {
            Double amount = orderService.getSalesAmountByTimeRange(startTime, endTime, status);
            return Result.success(amount);
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("获取销售额失败");
        }
    }
    
    /**
     * 获取商家在时间范围内的订单数量
     * GET /api/orders/count/merchant/{merchantId}/time-range
     */
    @GetMapping("/count/merchant/{merchantId}/time-range")
    public Result<Long> getMerchantOrderCountByTimeRange(@PathVariable @NotNull Long merchantId,
                                                       @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDateTime startTime,
                                                       @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDateTime endTime,
                                                       @RequestParam(required = false) Integer status) {
        try {
            long count = orderService.getMerchantOrderCountByTimeRange(merchantId, startTime, endTime, status);
            return Result.success(count);
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("获取订单数量失败");
        }
    }
    
    /**
     * 获取商家在时间范围内的销售额
     * GET /api/orders/sales/merchant/{merchantId}/time-range
     */
    @GetMapping("/sales/merchant/{merchantId}/time-range")
    public Result<Double> getMerchantSalesAmountByTimeRange(@PathVariable @NotNull Long merchantId,
                                                          @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDateTime startTime,
                                                          @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDateTime endTime,
                                                          @RequestParam(required = false) Integer status) {
        try {
            Double amount = orderService.getMerchantSalesAmountByTimeRange(merchantId, startTime, endTime, status);
            return Result.success(amount);
        } catch (BusinessException e) {
            return Result.badRequest(e.getMessage());
        } catch (Exception e) {
            return Result.error("获取销售额失败");
        }
    }
    
    /**
     * 生成订单号
     * GET /api/orders/generate-no
     */
    @GetMapping("/generate-no")
    public Result<String> generateOrderNo() {
        try {
            String orderNo = orderService.generateOrderNo();
            return Result.success(orderNo);
        } catch (Exception e) {
            return Result.error("生成订单号失败");
        }
    }
    
    /**
     * 检查订单是否可以取消
     * GET /api/orders/{id}/can-cancel
     */
    @GetMapping("/{id}/can-cancel")
    public Result<Boolean> canCancelOrder(@PathVariable @NotNull Long id) {
        try {
            boolean canCancel = orderService.canCancelOrder(id);
            return Result.success(canCancel);
        } catch (Exception e) {
            return Result.error("检查失败");
        }
    }
    
    /**
     * 检查订单是否可以退款
     * GET /api/orders/{id}/can-refund
     */
    @GetMapping("/{id}/can-refund")
    public Result<Boolean> canRefundOrder(@PathVariable @NotNull Long id) {
        try {
            boolean canRefund = orderService.canRefundOrder(id);
            return Result.success(canRefund);
        } catch (Exception e) {
            return Result.error("检查失败");
        }
    }
    
    /**
     * 获取订单统计数据
     * GET /api/orders/stats
     */
    @GetMapping("/stats")
    public Result<Map<String, Object>> getOrderStats(@RequestParam(required = false) Long merchantId,
                                                    @RequestParam(required = false) String startDate,
                                                    @RequestParam(required = false) String endDate) {
        try {
            Map<String, Object> stats = new HashMap<>();
            
            LocalDateTime start;
            LocalDateTime end;
            
            if (startDate != null && !startDate.isEmpty()) {
                // 将字符串转换为LocalDateTime，设置时间为当天开始
                start = LocalDateTime.parse(startDate + "T00:00:00");
            } else {
                start = LocalDateTime.now().withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0);
            }
            
            if (endDate != null && !endDate.isEmpty()) {
                // 将字符串转换为LocalDateTime，设置时间为当天结束
                end = LocalDateTime.parse(endDate + "T23:59:59");
            } else {
                end = LocalDateTime.now();
            }
            
            // 根据是否有merchantId参数来决定使用哪个方法
            if (merchantId != null) {
                // 获取特定商家的各状态订单数量
                stats.put("totalOrders", orderService.getMerchantOrderCountByTimeRange(merchantId, start, end, null));
                stats.put("pendingOrders", orderService.getMerchantOrderCountByTimeRange(merchantId, start, end, 1));
                stats.put("paidOrders", orderService.getMerchantOrderCountByTimeRange(merchantId, start, end, 2));
                stats.put("deliveringOrders", orderService.getMerchantOrderCountByTimeRange(merchantId, start, end, 3));
                stats.put("completedOrders", orderService.getMerchantOrderCountByTimeRange(merchantId, start, end, 4));
                stats.put("cancelledOrders", orderService.getMerchantOrderCountByTimeRange(merchantId, start, end, 5));
                
                // 获取特定商家的销售额
                stats.put("totalSales", orderService.getMerchantSalesAmountByTimeRange(merchantId, start, end, null));
                stats.put("completedSales", orderService.getMerchantSalesAmountByTimeRange(merchantId, start, end, 4));
            } else {
                // 获取所有商家的各状态订单数量
                stats.put("totalOrders", orderService.getOrderCountByTimeRange(start, end, null));
                stats.put("pendingOrders", orderService.getOrderCountByTimeRange(start, end, 1));
                stats.put("paidOrders", orderService.getOrderCountByTimeRange(start, end, 2));
                stats.put("deliveringOrders", orderService.getOrderCountByTimeRange(start, end, 3));
                stats.put("completedOrders", orderService.getOrderCountByTimeRange(start, end, 4));
                stats.put("cancelledOrders", orderService.getOrderCountByTimeRange(start, end, 5));
                
                // 获取所有商家的销售额
                stats.put("totalSales", orderService.getSalesAmountByTimeRange(start, end, null));
                stats.put("completedSales", orderService.getSalesAmountByTimeRange(start, end, 4));
            }
            
            return Result.success(stats);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("获取统计数据失败: " + e.getMessage());
        }
    }
    
    /**
     * 将OrderDTO转换为Order实体
     */
    private Order convertToOrder(OrderDTO orderDTO) {
        Order order = new Order();
        order.setUserId(orderDTO.getUserId());
        order.setMerchantId(orderDTO.getMerchantId());
        order.setAddressId(orderDTO.getAddressId());
        order.setPaymentMethod(orderDTO.getPaymentMethod());
        order.setRemark(orderDTO.getRemark());
        
        // 设置总价
        if (orderDTO.getTotalPrice() != null) {
            order.setTotalPrice(new BigDecimal(orderDTO.getTotalPrice()));
        }
        
        // 转换订单明细项
        if (orderDTO.getItems() != null && !orderDTO.getItems().isEmpty()) {
            List<OrderDetail> orderDetails = new ArrayList<>();
            for (OrderDTO.OrderItemDTO item : orderDTO.getItems()) {
                OrderDetail detail = new OrderDetail();
                detail.setFoodId(item.getFoodId());
                detail.setFoodName(item.getFoodName());
                detail.setFoodImage(item.getFoodImage());
                detail.setPrice(new BigDecimal(item.getPrice()));
                detail.setQuantity(item.getQuantity());
                detail.setSubtotal(new BigDecimal(item.getSubtotal()));
                orderDetails.add(detail);
            }
            order.setOrderDetails(orderDetails);
        }
        
        return order;
    }
    
    /**
     * 根据状态码获取状态描述
     */
    private String getStatusMessage(Integer status) {
        switch (status) {
            case 1:
                return "订单已创建，等待支付";
            case 2:
                return "订单已支付";
            case 3:
                return "订单配送中";
            case 4:
                return "订单已完成";
            case 5:
                return "订单已取消";
            default:
                return "状态更新成功";
        }
    }
} 